package com.ace.slide.client.ui;

import com.ace.slide.client.listener.Listener;
import com.ace.slide.client.listener.ListenerEvent;
import com.ace.slide.client.service.SlideShowBuilderServiceAsync;
import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.fx.FxConfig;
import com.extjs.gxt.ui.client.state.CookieProvider;
import com.extjs.gxt.ui.client.state.StateManager;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.custom.ThemeSelector;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class LoginPanel extends ContentPanel
{

    private StateManager stateManager;

    private Viewport mainViewport;

    private ThemeSelector selector;
    private Button loginButton;
    private Button registerButton;
    private Button logoutButton;

    private TextField<String> password;
    private TextField<String> username;
    private TextField<String> firstName;
    private TextField<String> lastName;
    private TextField<String> email;

    private HorizontalPanel hPanel;

    private MessageBox progressBox;
    private Window popUpWindow;

    private FormPanel popUpForm;

    private Button popUpButton;
    private Button popUpCancelButton;
    private Listener loginListener;

    private SlideShowBuilderServiceAsync service;

    public LoginPanel()
    {

        service = Registry.get("builderService");

        stateManager = new StateManager();
        stateManager.setProvider(new CookieProvider(null, null, null, false));

        String name = stateManager.getString("name");

        selector = new ThemeSelector();
        selector.setWidth(125);

        loginButton = new Button("Login");

        registerButton = new Button("Register");

        logoutButton = new Button("Logout");

        hPanel = new HorizontalPanel();
        hPanel.setSpacing(10);
        hPanel.setHorizontalAlign(HorizontalAlignment.CENTER);
        hPanel.setAutoHeight(true);
        hPanel.setAutoWidth(true);
        hPanel.add(selector);
        hPanel.add(loginButton);
        hPanel.add(registerButton);
        hPanel.add(logoutButton);

        if (name != null)
        {
            loginButton.setVisible(false);
            registerButton.setVisible(false);
            logoutButton.setVisible(true);
            setHeading("Welcome, " + name + "!");
        }
        else
        {
            loginButton.setVisible(true);
            registerButton.setVisible(true);
            logoutButton.setVisible(false);
            setHeading("Welcome to Ace Slideshows, LLC!");
        }

        createPopUpWindow();

        setFrame(true);
        setScrollMode(Scroll.AUTO);
        setCollapsible(true);

        add(hPanel);
        addListeners();
    }

    public void createPopUpWindow()
    {

        password = new TextField<String>();
        password.setPassword(true);
        password.setFieldLabel("Password");

        username = new TextField<String>();
        username.setFieldLabel("Username");
        
        firstName = new TextField<String>();
        firstName.setFieldLabel("First Name");
        
        lastName = new TextField<String>();
        lastName.setFieldLabel("Last Name");
        
        email = new TextField<String>();
        email.setFieldLabel("Email");

        popUpButton = new Button("Login");

        popUpCancelButton = new Button("Cancel");

        popUpForm = new FormPanel();
        popUpForm.setHeaderVisible(false);
        popUpForm.setFrame(true);
        popUpForm.setWidth(350);
        popUpForm.add(firstName);
        popUpForm.add(lastName);
        popUpForm.add(username);
        popUpForm.add(password);
        popUpForm.add(email);
        popUpForm.addButton(popUpButton);
        popUpForm.addButton(popUpCancelButton);

        popUpWindow = new Window();
        popUpWindow.setFrame(true);
        popUpWindow.setClosable(false);
        popUpWindow.setWidth(360);
        popUpWindow.add(popUpForm);

    }

    private void addListeners()
    {
        loginButton.addSelectionListener(new SelectionListener<ComponentEvent>()
        {
            public void componentSelected(ComponentEvent ce)
            {
                mainViewport = (Viewport) Registry.get("mainViewport");
                if (popUpWindow.el() == null || popUpButton.getId().equals("register"))
                {
                	firstName.setVisible(false);
                	lastName.setVisible(false);
                	email.setVisible(false);
                    popUpButton.setText("Login");
                    popUpButton.setId("login");
                    popUpWindow.setHeading("Login");
                    mainViewport.add(popUpWindow);
                    mainViewport.layout();
                }
                popUpWindow.el().fadeIn(FxConfig.NONE);
                popUpWindow.center();
                username.focus();
            }
        });

        registerButton.addSelectionListener(new SelectionListener<ComponentEvent>()
        {
            public void componentSelected(ComponentEvent ce)
            {
                mainViewport = (Viewport) Registry.get("mainViewport");
                if (popUpWindow.el() == null || popUpButton.getId().equals("login"))
                {
                	firstName.setVisible(true);
                	lastName.setVisible(true);
                	email.setVisible(true);
                    popUpButton.setText("Register");
                    popUpButton.setId("register");
                    popUpWindow.setHeading("Register");
                    mainViewport.add(popUpWindow);
                    mainViewport.layout();
                }
                popUpWindow.el().fadeIn(FxConfig.NONE);
                popUpWindow.center();
                firstName.focus();
            }
        });

        logoutButton.addSelectionListener(new SelectionListener<ComponentEvent>()
        {
            public void componentSelected(ComponentEvent ce)
            {
                stateManager.set("name", "");
                loginListener.change(new ListenerEvent(this, "Login", true, false));
            }
        });

        popUpButton.addSelectionListener(new SelectionListener<ComponentEvent>()
        {
            public void componentSelected(ComponentEvent ce)
            {
                AsyncCallback<String> callback = new AsyncCallback<String>()  {
                	public void onSuccess(String name)
                    {
                        if (!name.equals(""))
                        {
                            stateManager.set("name", name);
                            Info.display("Welcome " + name + "!",
                                    "You have successfully logged in.");
                            progressBox.hide();
                            popUpWindow.el().fadeOut(FxConfig.NONE);
                            loginListener.change(new ListenerEvent(this, "Login", false, true));
                        }
                        else
                        {
                            MessageBox
                                    .alert(
                                            "Sorry",
                                            "You entered an invalid username or password. Please try something else.",
                                            null);
                            progressBox.hide();
                        }

                    }

                    public void onFailure(Throwable caught)
                    {
                        MessageBox.alert("Error",
                                "There was an error with the server. Please try again.", null);
                        progressBox.hide();
                    }
                };
            	
            	if (ce.component.getId().equals("register"))
                {
                    progressBox =
                            MessageBox.wait("Register", "Attempting to register, please wait...",
                                    "Registering...");
                    service.processRegister(firstName.getValue(), lastName.getValue(), username.getValue(), password.getValue(), email.getValue(), callback);
                }
                else if (ce.component.getId().equals("login"))
                {
                    progressBox =
                            MessageBox.wait("Login", "Attempting to login, please wait...",
                                    "Loggin in...");
                    service.processLogin(username.getValue(), password.getValue(), callback);
                }
            }
        });

        popUpCancelButton.addSelectionListener(new SelectionListener<ComponentEvent>()
        {
            public void componentSelected(ComponentEvent ce)
            {
                username.reset();
                password.reset();
                email.reset();
                firstName.reset();
                lastName.reset();
                popUpWindow.el().fadeOut(FxConfig.NONE);
            }
        });
    }

    public void addLoginListener(Listener listener)
    {
        this.loginListener = listener;
    }
}